home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
mutt
/
cmode.mut
< prev
next >
Wrap
Text File
|
1988-10-10
|
11KB
|
375 lines
;; cmode.mut : an electric C mode
;; Electric C mode is designed to help keep your C code formatted "as you
;; code". You don't have to remember anything special - as you type, what
;; you type is looked at and may trigger certain actions. This is a
;; minimalist C mode ment to enable you to keep your C code formatted in a
;; consistant manner. The only extensive help is for comments.
;; Characters that trigger formatting:
;; "{": When a "{" is pressed, the following will happen:
;; - If the space bar is pressed, "{ }" is generated and the cursor is
;; put between the braces.
;; - If Enter is pressed:
;; And the rest of the line is blank, you will get something like:
;; if (a) { or if (a)
;; cursor {
;; } cursor
;; }
;; depending on where the "{" was. The cursor is indented by the
;; amount specified by "indent-level".
;; If the rest of the line was not blank, a newline-and-indent is
;; done and the text after the { is indented.
;; For example:
;; if (a) foo(): if a "{ Enter" is done before the foo()
;; you will get:
;; if (a) {
;; foo()
;; - Otherwise, a "{" is inserted.
;; Backspace: Behaves like backspacing over spaces even when backspacing
;; over tabs.
;; Newline (control-J): Used to give some white space after a variable
;; declaration block. The cursor is left at the same column as the start
;; of the declarations.
;; int j; => int j;
;; blank line
;; cursor
;; "/": Comment assistance.
;; - If "*" is pressed and the rest of the line is blank and there is
;; text to the left of the "/", "/* */" is generated and the cursor
;; is put in the middle of the comment. This is for end of line
;; comments like: if (a) foobar(); /* comment */
;; - If "*" is pressed and the entire line is blank, block comment mode
;; is entered. In this mode, your comment will autowrap at the
;; comment-wrap-column. When you hit Enter or autowrap, stars are
;; put in the proper place, whitespace is added to match the
;; previous comment line. If you press Enter "/", comment mode will
;; terminate. "*/" or "*" blanks "/" will also terminate comment
;; mode. If you want to get out of comment mode without using the
;; above, execute "nocomment".
;; Examples:
;; /*
;; * Comment
;; * Indented a bit
;; * Next line follows the indent.
;; */
;; /*
;; ** Another comment style
;; */
;; - Otherwise, a "/" is inserted.
;; Meta-J: Format a C block comment.
;; If you munge a block comment and want to set it right, use this.
;; This formats all the lines between the dot and mark inclusive.
;; Put the region around the comment (or the part of the comment you want
;; to format) and press M-J. The comment is commented in the format of
;; comment mode.
;; Notes:
;; To make sure that line breaks are preserved, insert blank lines at
;; the breaks. The blank lines will be deleted after the comment
;; is formatted.
;; To change the indent level of the block, indent the first line of
;; the region to where you want.
;; Control-U Meta-J: Format a C boxed comment.
;; Same as format block comment except the comment is boxed:
;; /********************************
;; * Comment *
;; ********************************/
;; You can convert between boxed and block comments by just reformatting.
;; C Durland
(const
indent-level 2
comment-wrap-column 76
C-stars " *" ; comment body stars: " *" or "**".
comet " */" ; comment end stars: " */" or "*/".
; number of blank lines before and after text in boxed comment
boxed-comment-space 1
boxed-comment-trailing-blanks 1 ; blanks between text and *
boxed-comment-edge-stars "*" ; right edge stars: "*" or "**"
Enter-key-action "newline-and-indent"
)
(defun
c-mode ; set up electric C mode
{
(tab-stops 0)(word-wrap 0)
(bind-local-key Enter-key-action "C-M")
(bind-local-key "C-mode-{" "{")
(bind-local-key "after-declare" "^J")
(bind-local-key "Dr.commento" "/")
(bind-local-key "BS-untabify" "^H")
(bind-local-key "format-C-comment" "M-J")
}
)
(include me.h)
(include bs_untab.mut)
(defun
"C-mode-{" ; handle {
{
(int key n)
(insert-text "{")(update)
(switch (key (get-key))
Space-bar ; try for { . } else just insert a blank
{
(if (looking-at '\ *$') ; only whitespace 'til end of line
{ (insert-text " }")(previous-character)(previous-character) }
(insert-text " ")
)
}
Enter-key
{
(newline-and-indent)(n (current-column))
(if (looking-at '\ *$') ; white space to end of line
{
(insert-text "}")
(beginning-of-line)(open-line)
})
(to-col (+ n indent-level))
}
default (exe-key key)
)
}
after-declare ; properly indent after a var declare
{
(newline-and-indent)(beginning-of-line)(open-line)
(forward-line 1)(end-of-line)
}
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;; Comment mode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun
Dr.commento ; handle "/" & start up comment mode if need be
{
(int key col)
(insert-text "/")(update)
; Check to see if starting a comment. No "*" => no comment
(if (!= (key (get-key)) 0x2A) { (exe-key key)(done) } )
; check to see if this is a comment block
(insert-text "*")
(col (current-column))(beginning-of-line)
(if (not (looking-at '\ */\*\ *$')) ; ws/*ws
{ ; its not a comment block - give them "/* */"
(current-column col)
(if (looking-at '\ *$') ; only if at end of line
{ (insert-text " */")(arg-prefix 3)(previous-character) } )
(done)
})
; turn on block comment mode
(current-column col)(buffer-var comment-offset (- col 2))
(word-wrap comment-wrap-column)
(bind-local-key "Dr.CR" "C-M")
(bind-local-key "C-mode-/" "/")
(insert-text " ")
(msg "Consulting Dr. Commento")
}
nocomment ; Turn off comment mode
{
(bind-local-key Enter-key-action "C-M")
(bind-local-key "Dr.commento" "/")
(word-wrap 0)
(msg "end comment")
}
Dr.CR ; handle Enter while in comment mode
{
(int key)
(msg "Still consulting Dr. Commento")
(open-line)(beginning-of-line)
(if (looking-at '\ *.\ *\*+\(\ *\)') ; [ws]/*[ws] | ws*[*...][ws]
{
(forward-line 1)
(to-col (buffer-var comment-offset))
(insert-text C-stars (get-matched '\1'))
})
}
C-mode-/ ; handle "/" in comment mode
{
(int col)
(col (current-column))
(previous-character)
(if (looking-at '\*') ; "*/" => ending comment
{ (nocomment)(goto ick) })
(beginning-of-line)
(if (looking-at '\ *\*+\ *$') ; [ws]*[*...][ws]/
{
(current-column (buffer-var comment-offset))
(kill-line)
(insert-text comet)
(nocomment)
(done)
})
(label ick)
(current-column col)(insert-text "/")
}
)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;; Format block comment ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun
add-stars(int n) HIDDEN
{
(int j)
(j (+ n 1))
(while (!= 0 (-= j 1)) (insert-text "*"))
}
format-C-comment
{
(bool start-comment end-comment boxed-comment)
(int offset j)
(string code-buffer 50)
(boxed-comment (arg-flag))
(start-comment (end-comment FALSE))
(code-buffer (buffer-name -1))
(delete-region-as-block)
(switch-to-buffer scratch-buffer)
(buffer-flags -1 BFGone)(clear-buffer -1)
(insert-register 0)
(beginning-of-buffer)
(if (re-search-forward '^\ */\*') ; ^[ws]/*
{
(start-comment TRUE)
(offset (- (current-column) 2))
(beginning-of-line)
(re-query-replace '^\ */\*+' "") ; get rid of ^[ws]/*[*...]
}
{
(if (search-forward C-stars)
(offset (- (current-column) 2))
{
; else get the block offset from left margin
(beginning-of-line)
(while (isspace) (next-character))
(offset (current-column))
}
)
}
)
(beginning-of-buffer)
(if (re-search-forward '\*/\ *$') ; */[ws]$
{
(end-comment TRUE)
(beginning-of-line)
(re-query-replace '\ *\*+/\ *$' "") ; get rid of [ws]*[*...]/[ws]$
})
(beginning-of-buffer)
(re-query-replace '^\ *\*+' "") ; get rid of [white-space]*[*...]
(beginning-of-buffer)
(re-query-replace '\ *\*+$' "") ; get rid of [white-space]*[*...]$
(msg "Formatting comment ...")
(beginning-of-buffer)
(adjust-lines
10000
(- comment-wrap-column offset 1
(if boxed-comment
(+ (strlen boxed-comment-edge-stars) boxed-comment-trailing-blanks)
0
))
FALSE
)
(beginning-of-buffer)
; put /*, * and */ in front of text
(if start-comment
{
(to-col offset)(insert-text '/*')
(if boxed-comment
{
(if (not (looking-at '\ *$')) (open-line))
(add-stars (- comment-wrap-column (current-column)))
(insert-text boxed-comment-edge-stars)
(j boxed-comment-space)
(while (<= 0 (-= j 1))
{
(newline-and-indent)(insert-text C-stars)
(to-col comment-wrap-column)(insert-text boxed-comment-edge-stars)
})
})
(forward-line 1)
})
(while (not (EoB))
{
(if (looking-at '^$')
{ (arg-prefix 1)(kill-line)(continue) } ; remove blank lines
{ ; else prepend *
(to-col offset)(insert-text C-stars)
(if boxed-comment
{
(end-of-line) (to-col comment-wrap-column)
(insert-text boxed-comment-edge-stars)
})
}
)
(forward-line 1)
})
(if end-comment
{
(to-col offset)
(if boxed-comment
{
(j boxed-comment-space)
(while (<= 0 (-= j 1))
{
(insert-text C-stars)
(to-col comment-wrap-column)(insert-text boxed-comment-edge-stars)
(newline)(to-col offset)
})
(insert-text C-stars)
(add-stars (- comment-wrap-column (current-column)))
(insert-text boxed-comment-edge-stars "/")
}
(insert-text comet)
)
})
; replace comment
(beginning-of-buffer)(set-mark)(end-of-buffer)
(clear-register 0)(append-to-register 0)
(msg "Comment formatted.")
(switch-to-buffer code-buffer)
(exchange-dot-and-mark) ; in case buffer was displayed more than once
(insert-register 0)
; clean up
(clear-buffer (attached-buffer scratch-buffer))
}
)
(defun
delete-region-as-block HIDDEN
{
(byte type)(int left-edge width height)(INT size)
(region-stats (loc type))
(if (== type MARK-ABOVE-DOT)(exchange-dot-and-mark))
(beginning-of-line)
(arg-prefix height)(kill-line)
}
)